package com.metro.activation.web.interceptor;

import com.metro.activation.common.annotation.SaveLog;
import com.metro.activation.sys.beans.entity.LogUserAccessEntity;
import com.metro.activation.sys.beans.vo.LogUserAccess;
import com.metro.activation.sys.service.inf.ILogUserAccessService;
import com.metro.core.annotation.BusinessDesc;
import com.metro.core.user.BaseUserInfo;
import com.metro.utils.TokenPool;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 系统公共业务日志
 * @author xk
 * @since [0.0.1]
 * @version [0.0.3, 2016年8月24日]
 */
public class BusinessDescInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private ILogUserAccessService loguseraccessService;

	/**
	 * 日志公共类
	 */
	private Logger log = LoggerFactory.getLogger(com.metro.core.web.BusinessDescInterceptor.class);

	/**
	 * {方法的功能/动作描述}
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws Exception
	 * @exception {说明在某情况下,将发生什么异常}
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
	    request.setAttribute("_requestStartTime", System.currentTimeMillis());
	    TokenPool.newToken();
	    return true;
	}

	/**
	 * {方法的功能/动作描述}
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @param modelAndView
	 * @throws Exception
	 * @exception {说明在某情况下,将发生什么异常}
	 */
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	    try {
            HandlerMethod hd = (HandlerMethod) handler;
            Method method = hd.getMethod();
            if (!method.isAnnotationPresent(BusinessDesc.class)) {
                log.debug(method.getDeclaringClass().getName() + "." + method.getName() + "没有添加业务描述");
            }

            if (hd.getMethod().isAnnotationPresent(BusinessDesc.class)) {
                BusinessDesc businessDesc = hd.getMethod().getAnnotation(BusinessDesc.class);
                String requestURL = request.getRequestURL().toString();
                String sessionId = request.getSession().getId().toString();
                String getRemoteAddr = request.getRemoteAddr();
                String requestMethod = request.getMethod();
                String queryString = request.getQueryString();
                long startTime = (long)request.getAttribute("_requestStartTime");
                long endTime = System.currentTimeMillis();
                long executeTime = endTime - startTime ;
                Subject currentUser = SecurityUtils.getSubject();
                Long userId = null;
                String userName = null;
                if(currentUser != null && currentUser.getPrincipal() != null){
                    BaseUserInfo currUserInfo  = (BaseUserInfo)currentUser.getPrincipal();
                    userId = currUserInfo.getUserId();
                    userName = currUserInfo.getUserName();
                }
                LogUserAccess logInfo = new LogUserAccess();
                logInfo.setThreadToken(TokenPool.getToken());
                logInfo.setSubsysCode(null);
                logInfo.setModuleName(businessDesc.ModuleDesc());
                logInfo.setMethodName(businessDesc.MethodDesc());
                logInfo.setRequestUrl(requestURL);
                logInfo.setUserAgent(request.getHeader("User-Agent"));
                logInfo.setRequestMethod(requestMethod);
                logInfo.setUserIp(getRemoteAddr);
                logInfo.setAccessStartTime(startTime);
                logInfo.setAccessEndTime(endTime);
                logInfo.setExecuteTime(executeTime);
                logInfo.setSessionid(sessionId);
                logInfo.setUserId(userId);
                logInfo.setUserName(userName);
                if(method.isAnnotationPresent(SaveLog.class)){
                    SaveLog saveLog = method.getAnnotation(SaveLog.class);
                    String need = saveLog.needSave();
                    logInfo.setSubsysCode(need);
                    loguseraccessService.save(logInfo);
                }

                log.info("user access log: {}", logInfo);
                
            } 
        } catch (Exception ex) {
            log.error("业务日志出错", ex);
            return;
        }
	    
	}

	/**
	 * {方法的功能/动作描述}
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @param ex
	 * @throws Exception
	 * @exception {说明在某情况下,将发生什么异常}
	 */
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
	}
}
